package org.lucene;

import java.io.File;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopFieldCollector;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class LuceneSortSample {
	public static void main(String[] args) {
		try {

			String path = "z:/index";
			Analyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_41);
			Similarity similarity = new MySimilarity();

			boolean isIndex = false; // true:要索引,false:表示要搜索
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_41, analyzer);
//			iwc.setSimilarity(similarity); // 设置相关度
			Directory dir = FSDirectory.open(new File(path));
			if (isIndex) {

				IndexWriter writer = new IndexWriter(dir, iwc);

				Document doc = new Document();
				doc.add(new TextField("Name", "java 开发人员", Field.Store.YES));
				doc.add(new TextField("Info", "招聘 网站开发人员,要求一年或以上工作经验", Field.Store.YES));
				doc.add(new StringField("Time", "20100201", Field.Store.YES));
				writer.addDocument(doc);

				doc = new Document();
				doc.add(new TextField("Name", "高级 开发 人员(java 方向)", Field.Store.YES));
				doc.add(new TextField("Info", "需要有四年或者以上的工作经验,有大型项目实践,java基本扎实", Field.Store.YES));
				doc.add(new StringField("Time", "20100131", Field.Store.YES));
				writer.addDocument(doc);

				doc = new Document();
				doc.add(new TextField("Name", "北京 php 开发 工程师 高级 职位", Field.Store.YES));
				doc.add(new TextField("Info", "主要是维护公司的网站php开发,能独立完成网站的功能", Field.Store.YES));
				doc.add(new StringField("Time", "20100201", Field.Store.YES));
				writer.addDocument(doc);				

				doc = new Document();
				doc.add(new TextField("Name", "北京 php 高级 开发", Field.Store.YES));
				doc.add(new TextField("Info", "主要是维护公司的网站php开发,能独立完成网站的功能", Field.Store.YES));
				doc.add(new StringField("Time", "20100201", Field.Store.YES));
				writer.addDocument(doc);				
				
				doc = new Document();
				doc.add(new TextField("Name", "php 开发 工程师  北京", Field.Store.YES));
				doc.add(new TextField("Info", "主要是维护公司的网站php开发,能独立完成网站的功能", Field.Store.YES));
				doc.add(new StringField("Time", "20100201", Field.Store.YES));
				writer.addDocument(doc);

				doc = new Document();
				doc.add(new TextField("Name", "4 linux 管理员", Field.Store.YES));
				doc.add(new TextField("Info", "管理及维护公司的linux服务器,职责包括完成mysql数据备份及日常管理,apache的性能调优等", Field.Store.YES));
				doc.add(new StringField("Time", "20100201", Field.Store.YES));
				writer.addDocument(doc);

				doc = new Document();
				doc.add(new TextField("Name", "5 lucene 开发 工作师", Field.Store.YES));
				doc.add(new TextField("Info", "需要两年或者以上的从事lucene java 开发工作的经验,需要对算法,排序规则等有相关经验,java水平及基础要扎实", Field.Store.YES));
				doc.add(new StringField("Time", "20100131", Field.Store.YES));
				writer.addDocument(doc);

				doc = new Document();
				doc.add(new TextField("Name", "6 php 软件工程师", Field.Store.YES));
				doc.add(new TextField("Info", "具有大量的php开发经验,如熟悉 java 开发,数据库管理则更佳", Field.Store.YES));
				doc.add(new StringField("Time", "20100130", Field.Store.YES));
				writer.addDocument(doc);
				writer.commit();				
				writer.close();
				System.out.println("数据索引完成");
			} else {
				IndexReader reader = DirectoryReader.open(dir);
				IndexSearcher search = new IndexSearcher(reader);
//				search.setSimilarity(similarity);

//				String fiels[] = { "Name", "Info" };
				String fiels[] = { "Name" };

				
				PhraseQuery pq = new PhraseQuery();
				pq.setSlop(10);
				pq.add(new Term("Name", "php"));
				pq.add(new Term("Name", "开发"));

//				PhraseQuery bq = new PhraseQuery();
				BooleanQuery bq = new BooleanQuery();
				for (int i = 0; i < fiels.length; i++) {
					String keyWords = "php 开发";
					String[] token = keyWords.split(" ");  

					for (int j = 0;j<token.length;j++) {
						String tKeyWord = token[j];
						String tFeild = fiels[i];
						TermQuery tq = new TermQuery(new Term(fiels[i], tKeyWord));

						if (tFeild.equals("Name")) { // 在Name这一个Field需要给大的比重
							tq.setBoost(100.0f);
						} else {
							tq.setBoost(0.0f); // 其他的不需要考滤
						}
						
						bq.add(tq, BooleanClause.Occur.SHOULD); // 关键字之间是 "或"
																// 的关系
					}
				}
				System.out.println("搜索条件Query:" + pq.toString());
				System.out.println();
				Sort sort = new Sort();
//				SortField sf1=new SortField("Name", SortField.FIELD_SCORE,true);
//				sort.setSort(SortField.FIELD_SCORE);
//				Sort sort = new Sort(new SortField[]{new SortField(null,SortField.Type.SCORE,false),new SortField("Time", SortField.Type.INT,true)});  
//				Sort sort = new Sort(new SortField[] { new SortField(null, (Parser) SortField.FIELD_SCORE, false), new SortField("Time", SortField.FIELD_DOC, true) });
				// 先按记录的得分排序,然后再按记录的发布时间倒序
				TopFieldCollector collector = TopFieldCollector.create(sort, 10, false, true, false, false);

				long l = System.currentTimeMillis();
				search.search(pq, collector);
				TopDocs tDocs = collector.topDocs();

				ScoreDoc sDocs[] = tDocs.scoreDocs;

				int len = sDocs.length;

				for (int i = 0; i < len; i++) {
//					System.out.println("=================================start======================================");
					ScoreDoc tScore = sDocs[i];
					float score = tScore.score;
					
					int docId = tScore.doc;
					Explanation exp = search.explain(pq, docId);
					
					Document tDoc = search.doc(docId);
					String Name = tDoc.get("Name");
					String Info = tDoc.get("Info");
					String Time = tDoc.get("Time");
					
					// System.out.println(exp.toString());　如果需要打印文档得分的详细信息则可以通过此方法
					System.out.println(score +"\tDocId:" + docId + "\tName:" + Name);
//					System.out.println("DocId:" + docId + "\tName:" + Name + "\tTime:" + Time + "\tInfo:" + Info);
//					System.out.println(exp.toString());
//					System.out.println("=================================end======================================");
				}
				l = System.currentTimeMillis() - l;
				System.out.println("搜索用时:" + l + "ms");
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}